package com.micro.ai.files.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.micro.ai.commons.exception.BusinessException;
import com.micro.ai.files.entity.FileShare;
import com.micro.ai.files.mapper.FileShareMapper;
import com.micro.ai.files.service.FileShareService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/**
 * 文件分享服务实现
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@Service
public class FileShareServiceImpl extends ServiceImpl<FileShareMapper, FileShare> implements FileShareService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FileShare create(FileShare share) {
        if (share == null) {
            throw new BusinessException("F0000", "文件分享信息不能为空");
        }
        
        if (!StringUtils.hasText(share.getFileId())) {
            throw new BusinessException("F0000", "文件ID不能为空");
        }
        
        // 生成分享令牌
        String shareToken = generateShareToken();
        share.setShareToken(shareToken);
        
        // 生成提取码（如果需要）
        if (share.getShareType() != null && share.getShareType().equals("password")) {
            if (!StringUtils.hasText(share.getShareCode())) {
                share.setShareCode(generateShareCode());
            }
        }
        
        if (share.getIsAllowPreview() == null) {
            share.setIsAllowPreview(true);
        }
        if (share.getIsAllowDownload() == null) {
            share.setIsAllowDownload(true);
        }
        if (share.getDownloadCount() == null) {
            share.setDownloadCount(0);
        }
        if (share.getViewCount() == null) {
            share.setViewCount(0);
        }
        
        LocalDateTime now = LocalDateTime.now();
        share.setCreatedAt(now);
        share.setUpdatedAt(now);
        
        boolean success = this.save(share);
        if (!success) {
            throw new BusinessException("F0003", "创建文件分享失败");
        }
        
        log.info("创建文件分享成功: shareId={}, fileId={}, shareToken={}", 
                share.getId(), share.getFileId(), share.getShareToken());
        return share;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FileShare update(String id, FileShare share) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("F0000", "分享ID不能为空");
        }
        if (share == null) {
            throw new BusinessException("F0000", "文件分享信息不能为空");
        }
        
        FileShare existing = this.getById(id);
        if (existing == null) {
            throw new BusinessException("F0002", "文件分享不存在: " + id);
        }
        
        share.setId(id);
        share.setUpdatedAt(LocalDateTime.now());
        
        boolean success = this.updateById(share);
        if (!success) {
            throw new BusinessException("F0003", "更新文件分享失败");
        }
        
        log.info("更新文件分享成功: shareId={}", id);
        return share;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("F0000", "分享ID不能为空");
        }
        
        FileShare share = this.getById(id);
        if (share == null) {
            throw new BusinessException("F0002", "文件分享不存在: " + id);
        }
        
        boolean success = this.removeById(id);
        if (!success) {
            throw new BusinessException("F0003", "删除文件分享失败");
        }
        
        log.info("删除文件分享成功: shareId={}, fileId={}", id, share.getFileId());
    }

    @Override
    public FileShare getByShareToken(String shareToken) {
        if (!StringUtils.hasText(shareToken)) {
            return null;
        }
        
        LambdaQueryWrapper<FileShare> query = new LambdaQueryWrapper<>();
        query.eq(FileShare::getShareToken, shareToken);
        
        FileShare share = this.getOne(query);
        
        // 检查是否过期
        if (share != null && share.getExpireAt() != null && share.getExpireAt().isBefore(LocalDateTime.now())) {
            log.warn("分享已过期: shareToken={}, expireAt={}", shareToken, share.getExpireAt());
            return null;
        }
        
        return share;
    }

    @Override
    public boolean validateSharePassword(String shareToken, String password) {
        FileShare share = getByShareToken(shareToken);
        if (share == null) {
            return false;
        }
        
        // 这里应该使用加密比较，简化处理
        if (share.getShareType() != null && share.getShareType().equals("password")) {
            // 实际应该使用BCrypt等加密方式比较
            return share.getPasswordEncrypted() != null && share.getPasswordEncrypted().equals(password);
        }
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void incrementDownloadCount(String id) {
        FileShare share = this.getById(id);
        if (share != null) {
            share.setDownloadCount((share.getDownloadCount() == null ? 0 : share.getDownloadCount()) + 1);
            share.setUpdatedAt(LocalDateTime.now());
            this.updateById(share);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void incrementViewCount(String id) {
        FileShare share = this.getById(id);
        if (share != null) {
            share.setViewCount((share.getViewCount() == null ? 0 : share.getViewCount()) + 1);
            share.setUpdatedAt(LocalDateTime.now());
            this.updateById(share);
        }
    }

    @Override
    public Page<FileShare> pageQuery(int pageNum, int pageSize, String tenantId, 
                                     String fileId, String createdBy) {
        if (pageNum < 1) {
            pageNum = 1;
        }
        if (pageSize < 1 || pageSize > 100) {
            pageSize = 20;
        }
        
        Page<FileShare> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<FileShare> query = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(tenantId)) {
            query.eq(FileShare::getTenantId, tenantId);
        }
        if (StringUtils.hasText(fileId)) {
            query.eq(FileShare::getFileId, fileId);
        }
        if (StringUtils.hasText(createdBy)) {
            query.eq(FileShare::getCreatedBy, createdBy);
        }
        
        query.orderByDesc(FileShare::getCreatedAt);
        
        return this.page(page, query);
    }

    @Override
    public List<FileShare> listByFileId(String fileId) {
        LambdaQueryWrapper<FileShare> query = new LambdaQueryWrapper<>();
        query.eq(FileShare::getFileId, fileId)
             .orderByDesc(FileShare::getCreatedAt);
        
        return this.list(query);
    }

    @Override
    public List<FileShare> listByCreatedBy(String tenantId, String createdBy) {
        LambdaQueryWrapper<FileShare> query = new LambdaQueryWrapper<>();
        query.eq(FileShare::getTenantId, tenantId)
             .eq(FileShare::getCreatedBy, createdBy)
             .orderByDesc(FileShare::getCreatedAt);
        
        return this.list(query);
    }

    /**
     * 生成分享令牌
     */
    private String generateShareToken() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 生成提取码
     */
    private String generateShareCode() {
        return String.valueOf((int)(Math.random() * 9000) + 1000); // 4位数字
    }
}

